﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Skywave.Data
{
    [DataContract]
    public class ChartDataGeneratorAxisCustomFilters : ChartDataGeneratorAxis
    {

        private string _CustomFilters_Body;
        /// <summary>
        /// ...
        /// </summary>
        [DataMember]
        public string CustomFilters_Body
        {
            get { return _CustomFilters_Body; }
            set { _CustomFilters_Body = value; }
        }

        private string _CustomFilters_WherePlaceHolder;
        /// <summary>
        /// ...
        /// </summary>
        [DataMember]
        public string CustomFilters_WherePlaceHolder
        {
            get { return _CustomFilters_WherePlaceHolder; }
            set { _CustomFilters_WherePlaceHolder = value; }
        }

        private List<ChartDataGeneratorAxisCustomFilter> _CustomFilters = new List<ChartDataGeneratorAxisCustomFilter>();
        /// <summary>
        /// ...
        /// </summary>
        [DataMember]
        public List<ChartDataGeneratorAxisCustomFilter> CustomFilters
        {
            get { return _CustomFilters; }
            set { _CustomFilters = value; }
        }

        public override ChartDataGeneratorAxisCases GetCases(string prefixForNames, ChartDataGenerator parent)
        {
            string column_Primary_Name = parent.Filter_PrimaryColumn_FullName;
            if (_CustomFilters == null || _CustomFilters.Count == 0)
                throw new ArgumentException("CustomFilters property must contains at least one item.");
            //
            ChartDataGeneratorAxisCases r = new ChartDataGeneratorAxisCases();
            //
            string s1;
            string tempTable_Name = string.Format("#{0}table_{1}", prefixForNames, Security.RandomGenerator.CreateRandomString(5));
            //
            s1 = string.Format("{0}c", prefixForNames);
            r.ColumnsSQLs.Add(s1, string.Format("{0}.[Data]", tempTable_Name));
            //
            r.JoinClauses = new List<string>();
            r.JoinClauses.Add(string.Format("JOIN {0} ON {0}.[PrimaryColumnName] = {1}", tempTable_Name, column_Primary_Name));
            //
            int iCustomFilter = 1;
            foreach (var fe1 in _CustomFilters)
            {
                fe1.Filter.ParametersPrefix = string.Format("filter_{0}_", iCustomFilter);
                iCustomFilter++;
            }
            var qCF1 = (from xCF in _CustomFilters
                        select new
                        {
                            Key = xCF.Text,
                            SqlCommandString = xCF.Filter.GenerateSqlCommandString(_CustomFilters_Body, _CustomFilters_WherePlaceHolder),
                            Index = new int[1],
                            Aggregate = xCF.Aggregate
                        }).ToList();
            for (int i1 = 0; i1 < qCF1.Count; i1++)
            {
                var qItem1 = qCF1[i1];
                qItem1.Index[0] = i1 + 1;
            }
            r.Params = (from x1 in qCF1
                        from x2 in x1.SqlCommandString.Params
                        select x2).ToList();
            //
            string sql_CaseWhen = "";
            string sql_CaseWhenFormat = @"
					WHEN
						{0} IN
						(
							{1}
						)
					THEN
						N'{2}'
";
            foreach (var fe1 in qCF1)
            {
                sql_CaseWhen += string.Format(sql_CaseWhenFormat, parent.Filter_PrimaryColumn_FullName, fe1.SqlCommandString.CommandString, fe1.Key);
                if (fe1.Aggregate != null)
                    r.Aggregates.Add(fe1.Key, fe1.Aggregate);
            }
            //
            r.SqlInitialization = string.Format(@"
CREATE TABLE {0} 
(
	primaryColumnName INT,
	Data NVARCHAR(512) NULL,
	CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED 
	(
		primaryColumnName ASC
	)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]	
)
INSERT INTO
	{0}
		SELECT
			{1} AS primaryColumnName,
			(
				CASE
{2}
					ELSE
						NULL
				END
			) AS [Data]
		FROM
            {3} AS {4}", tempTable_Name, parent.Filter_PrimaryColumn_FullName, sql_CaseWhen, parent.Filter_TempTableName, parent.Filter_TableName);
            //
            return r;
        }

        public override void CopySettingsFrom(ChartDataGeneratorAxis other)
        {
            if (other == null)
                return;
            if (other is ChartDataGeneratorAxisCustomFilters)
            {
                ChartDataGeneratorAxisCustomFilters otherTyped = other as ChartDataGeneratorAxisCustomFilters;
                CustomFilters = (otherTyped.CustomFilters == null) ? null : otherTyped.CustomFilters.ToList();
                CustomFilters_Body = otherTyped.CustomFilters_Body;
                CustomFilters_WherePlaceHolder = otherTyped.CustomFilters_WherePlaceHolder;
                MaxCaseCount = (otherTyped.MaxCaseCount == null) ? null : (int?)otherTyped.MaxCaseCount.Value; ;
                PointTextSeperator = otherTyped.PointTextSeperator;
            }

        }
        public override void CopyTo(ChartDataGeneratorAxis target)
        {
            if (target == null)
                return;
            base.CopyTo(target);
            if (target is ChartDataGeneratorAxisCustomFilters)
            {
                ChartDataGeneratorAxisCustomFilters target_Typed = target as ChartDataGeneratorAxisCustomFilters;
                target_Typed.CopySettingsFrom(this);
            }
        }

        public override object Clone()
        {
            return ObjectHelper.CloneUsingSerialization(this, typeof(ChartDataGeneratorAxisCustomFilters)) as ChartDataGeneratorAxisCustomFilters;
        }
    }
}
